# coding=utf-8

import os
import urllib.request
import time

#=====================
#      网络获取
#=====================


class FetcherInfo:

    def __init__(self):
        self.ua = 'bingwp'
        self.referer = ''
        self.open_timeout = 120
        self.retry_count = 2
        self.retry_interval = 1


class Fetcher:

    '''web获取器'''

    def __init__(self, fetcher_info=None):
        if fetcher_info == None:
            fetcher_info = FetcherInfo()
        
        self.referer = fetcher_info.referer
        self.info = fetcher_info

        # no proxy
        proxy = urllib.request.ProxyHandler({})
        # opener
        self.opener = urllib.request.build_opener(proxy)

    def save_file(self, url, local_path):
        if os.path.exists(local_path):
            print(local_path, '文件已存在')
            return 0

        byte_data = self.fetch_url(url)
        data_len = len(byte_data)

        if data_len > 0:
            with open(local_path, 'wb') as f:
                f.write(byte_data)
        return data_len

    def fetch_url(self, url):
        '''返回bytes'''
        # 重试次数
        retry = self.info.retry_count

        # request对象
        req = urllib.request.Request(url)
        req.add_header('User-Agent', self.info.ua)

        # 重试用的循环
        while True:
            try:
                # r是HTTPResponse对象
                r = self.opener.open(req,
                                     timeout=self.info.open_timeout
                                     )
                ret_data = r.read()
                return ret_data

            except Exception as e:
                print('! 下载时出现异常', url)
                print('! 可能是网址错误、服务器抽风、下载超时等等')
                print('! 详细异常信息:', type(e), '\n', e, '\n')

            retry -= 1
            if retry <= 0:
                break

            print('{0}秒后重试，剩余重试次数：{1}次\n'.
                  format(self.info.retry_interval, retry)
                  )
            time.sleep(self.info.retry_interval)

        print('重试次数用完，下载失败')
        return b''
